package com.yanqu.road.server.manger.config;

import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.vehicle.*;
import com.yanqu.road.entity.enums.eOccupationType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.player.UserVehicle;
import com.yanqu.road.entity.player.UserVehicleSoul;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.vehicle.VehicleSoulModule;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class VehicleSoulMgr extends TempMgr {

	//魂石的品质是1234，对应的是砖块个数

	//开孔数，消耗
	private static Map<Integer, VehicleSoulBlockInfo> vehicleSoulBlockInfoMap;

	//形状配置,唯一形状字符串
	private static Map<Integer, VehicleSoulShapeInfo> vehicleSoulShapeInfoMap;
	//相同砖块的所有形状的东西
	private static Map<Integer, List<VehicleSoulShapeInfo>> vehicleSoulShapeNumMap;

	//对应品质有多少词条，对应品质合成后会有什么奖励，对应品质合成升级品质的概率
	private static Map<Integer, VehicleSoulQualityInfo> vehicleSoulQualityInfoMap;

	//副词条 资质 权重
	private static Map<Integer, Integer> entryQualityWeightMap;


	//洗练词条消耗
	private static List<String> washEntryCostList;

	//赚钱加成配置
	private static List<List<Integer>> earnSpeedList;

    public static final int ONCE_SEND_VEHICLE_SOUL_COUNT = 200;

	//保底无双品质合成次数
	public static int VEHICLES_PEERLESS_GUARANTEES = 180;

	//转换道具
	public static int vehiclesTurnCostItemCq = 0; //传奇
	public static int vehiclesTurnCostItemWs = 0; //无双

	private static RandomHelper threadSafeRandom = new RandomHelper();

	//弄成日志格式的魂石资质记录
	public static String getSoulAllQaStr(UserVehicleSoul userVehicleSoul){
		List<String> infoStrList = new ArrayList<>();
		Map<Integer, List<Integer>> entryMap = userVehicleSoul.getEntryMap();
		for(List<Integer> infoList : entryMap.values()){
			infoStrList.add(infoList.get(1) + "," + infoList.get(2));
		}
		return StringUtils.listToString(infoStrList,"|");
	}

	//日志弄成每种品质的魂石的个数的形式 1:100|2:20（1品质100个|2品质20个）
	public static String getSoulQaStr(List<UserVehicleSoul> soulList){
		Map<Integer,Integer> aaMap = new ConcurrentHashMap<>();
		for(UserVehicleSoul soul : soulList){
			aaMap.put(soul.getOccList().size(),aaMap.getOrDefault(soul.getOccList().size(),0) + 1);
		}

		List<String> aaaList = new ArrayList<>();
		for(int quality : aaMap.keySet()){
			aaaList.add(quality + ":" + aaMap.get(quality));
		}

		return StringUtils.listToString(aaaList,"|");
	}

	//日志要的格式，加成了多少赚速和资质和满盘奖励
	public static List<String> getSoulAddStrLog(GamePlayer player,UserVehicle userVehicle){
		List<String> resStrList = new ArrayList<>();
		List<Integer> addEarnList = getEarnAddList(player,userVehicle);
		long addQaValue = getQaAddValue(player,userVehicle);
		//赚钱加成和资质加成
		String str1 = "";
		String str2 = "";
		if(addEarnList.size() > 0){
			str1 = "赚钱:" + addEarnList.get(0) + ";资质:" + addQaValue;
			str2 = "" + addEarnList.get(1);
		}else{
			str1 = "赚钱:" + 0 + ";资质:" + addQaValue;
			str2 = "0";
		}
		resStrList.add(str1);
		resStrList.add(str2);
		return resStrList;
	}

	//获取赚钱加成
	public static List<Integer> getEarnAddList(GamePlayer player,UserVehicle userVehicle){
		List<Integer> addList = new ArrayList<>();
		if(userVehicle == null){
			return addList;
		}
		if(userVehicle.getPatronsId() != 0){
			UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(userVehicle.getPatronsId());
            PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userPatrons.getPatronsId());
            int addition = 0;
            if(patronsInfo != null){
                addition = (int)CurioMgr.getSkillAdditionBySkillType(eSkillType.OccupationSoulStoneAddSkill.getValue(), player, patronsInfo.getOccupation());
            }
			Map<Integer, UserVehicleSoul> userVehicleSoulMap = player.getModule(VehicleSoulModule.class).getUserVehicleSoulMap();
			addList = PatronsMgr.getVehicleSoulEarnAdditionList(userPatrons,userVehicle,userVehicleSoulMap, addition);
		}
		return addList;
	}

	//获得资质加成值
	public static long getQaAddValue(GamePlayer player,UserVehicle userVehicle){
		long addValue = 0;
		if(userVehicle == null){
			return addValue;
		}
		if(userVehicle.getPatronsId() != 0){
			UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(userVehicle.getPatronsId());
			Map<Integer, UserVehicleSoul> userVehicleSoulMap = player.getModule(VehicleSoulModule.class).getUserVehicleSoulMap();
			addValue = PatronsMgr.getVehicleSoulAddAbility(userPatrons,userVehicle,userVehicleSoulMap);
		}
		return addValue;
	}

    //用已经洗过了几次来拿消耗
    public static String getWashCost(int nowTimes){
    	if(nowTimes < washEntryCostList.size()){
    		return washEntryCostList.get(nowTimes);
		}

    	//最后用最大的一直洗
    	return washEntryCostList.get(washEntryCostList.size() - 1);
	}

    public static VehicleSoulBlockInfo getSoulBlockInfo(int blockNum){
    	return vehicleSoulBlockInfoMap.get(blockNum);
	}

	//开孔了多少返还玩家
    public static Property getSoulBlockConsume(int blockNum){
        Property consume = new Property();
        for(int i : vehicleSoulBlockInfoMap.keySet()){
            if(i <= blockNum && !"0".equals(vehicleSoulBlockInfoMap.get(i).getUpCost())){
                consume.addProperty(PropertyHelper.parseStringToProperty(vehicleSoulBlockInfoMap.get(i).getUpCost()));
            }
        }
    	return consume;
	}

	//就是configId
    public static VehicleSoulShapeInfo getShapeInfo(int shapeId){
		return vehicleSoulShapeInfoMap.get(shapeId);
	}

    public static List<Integer> randomOneShapeOccList(int occId,int num,boolean is4quality){
		List<Integer> occList = new ArrayList<>();
		if(occId != 0){
			for(int i = 0; i < num;i++){
				occList.add(occId);
			}
		}else{
			for(int i = 0; i < num;i++){
				occList.add(randomOneOcc(0));
			}
			//多块且全部一色再随机一次 不用了，说是不加这个坑 又要了，变成只有四级的
			if(occList.size() > 1 && is4quality){
				Map<Integer,Integer> occMap = new ConcurrentHashMap<>();
				boolean isSameColor = true;
				for(int i = 0;i+1 < occList.size();i++){
					occMap.put(i,occList.get(i));
					occMap.put(i+1,occList.get(i+1));
					int a = occList.get(i);
					int b = occList.get(i+1);
					if(a != b){
						isSameColor = false;
					}
				}
				if(isSameColor){
					int reloadValue = threadSafeRandom.next(0,1000);
					//重新随机一个让不是全部一样颜色
					if(reloadValue < GameConfig.VEHICLES_SOUL_PURE_CHANGE_PRO){
						int reloadIndex = threadSafeRandom.next(0,occList.size());
						occMap.put(reloadIndex,randomOneOcc(occList.get(reloadIndex)));
						occList = new ArrayList<>(occMap.values());
					}
				}
			}
		}
		return occList;
	}

	//合成的信息和词条有几条的，配在了一起
	public static VehicleSoulQualityInfo getQualityInfo(int quality){
		VehicleSoulQualityInfo qualityInfo = vehicleSoulQualityInfoMap.get(quality);
		return qualityInfo;
	}

    //生成魂石的时候随机词条
	public static Map<Integer,List<Integer>> randomOneShapeEntryList(VehicleSoulShapeInfo shapeInfo){
		Map<Integer,List<Integer>> entryMap = new ConcurrentHashMap<>();
		if(!vehicleSoulQualityInfoMap.containsKey(shapeInfo.getQuality())){
			return entryMap;
		}

		VehicleSoulQualityInfo 	qualityInfo = vehicleSoulQualityInfoMap.get(shapeInfo.getQuality());
		for(int i = 0; i < qualityInfo.getNum();i++){
			List<Integer> infoList = new ArrayList<>();
			//类型1的是对应职业加技能
			infoList.add(1);
			infoList.add(randomOneOcc(0));
			infoList.add(randomOneEntryOccQuality());
			infoList.add(0);
			entryMap.put(i,infoList);
		}
		return entryMap;
	}

	//随机一个词条属性
	public static List<Integer> randomOneShapeEntry(List<Integer> infoList){
    	int times = infoList.get(3) + 1;
		List<Integer> newInfoList = new ArrayList<>();
		//类型1的是对应职业加资质
		newInfoList.add(infoList.get(0));
		newInfoList.add(infoList.get(1));
		newInfoList.add(infoList.get(2));
		newInfoList.add(times);
		newInfoList.add(randomOneOcc(0));
		newInfoList.add(randomOneEntryOccQuality());
		return newInfoList;
	}

	//随机一个职位
	private static int randomOneOcc(int notThis){
		List<Short> occList = new ArrayList<>();
		for(eOccupationType occ : eOccupationType.values()){
			if(notThis != occ.getValue()){
				occList.add(occ.getValue());
			}
		}
		int randomOccIndex = threadSafeRandom.next(0,occList.size());
		int occId = occList.get(randomOccIndex);
		return occId;
	}

	//随机一个职业加多少资质
	private static int randomOneEntryOccQuality(){
		Map<Integer, Integer> gagaMap = new ConcurrentHashMap<>(entryQualityWeightMap);
		int qualityValue = 0;
		List<Integer> qaList = new ArrayList<>(gagaMap.keySet());
		List<Integer> weightList = new ArrayList<>(gagaMap.values());

		int totalWeight = 0;
		for (int weight : gagaMap.values()) {
			totalWeight += weight;
		}
		int randomNum = threadSafeRandom.next(0, totalWeight);
		for (int i = 0; i < weightList.size(); i++) {
			int value = weightList.get(i);
			if (randomNum < value) {
				qualityValue = qaList.get(i);
				break;
			}
			randomNum -= value;
		}

		return qualityValue;
	}

	//只会有一个
	public static VehicleSoulShapeInfo getQualityOneShapInfo(){
        List<VehicleSoulShapeInfo> allShapeInfoList = vehicleSoulShapeNumMap.get(1);
        return allShapeInfoList.get(0);
    }

	//随机一个品质，然后随机一个形状
	public static VehicleSoulShapeInfo randomOneShapeByWeight(Map<Integer,Integer> qaWeightMap){
		int quality = randomOneQuality(qaWeightMap);
		return randomOneShapeByQuality(quality);
	}

	public static VehicleSoulShapeInfo randomOneShapeByQuality(int quality){
		List<VehicleSoulShapeInfo> allShapeInfoList = vehicleSoulShapeNumMap.get(quality);
		if(allShapeInfoList.size() == 0){
			return null;
		}
		VehicleSoulShapeInfo info = null;

		int totalWeight = 0;
		for (VehicleSoulShapeInfo shapeInfo : allShapeInfoList) {
			totalWeight += shapeInfo.getWeight();
		}

		int randomNum = threadSafeRandom.next(0, totalWeight);
		for (int i = 0; i < allShapeInfoList.size(); i++) {
			VehicleSoulShapeInfo shapeInfo = allShapeInfoList.get(i);
			if (randomNum < shapeInfo.getWeight()) {
				info = allShapeInfoList.get(i);
				break;
			}
			randomNum -= shapeInfo.getWeight();
		}

		return info;
	}

    //随机一个品质
    private static int randomOneQuality(Map<Integer,Integer> qaWeightMap){
		int quality = 0;
		List<Integer> qaList = new ArrayList<>(qaWeightMap.keySet());
		List<Integer> weightList = new ArrayList<>(qaWeightMap.values());

		int totalWeight = 0;
		for (int weight : weightList) {
			totalWeight += weight;
		}
		int randomNum = threadSafeRandom.next(0, totalWeight);
		for (int i = 0; i < weightList.size(); i++) {
			int value = weightList.get(i);
			if (randomNum < value) {
				quality = qaList.get(i);
				break;
			}
			randomNum -= value;
		}

		return quality;
	}

	//合成是不是升星随机千分比
	public static boolean isComposeUp(int upWeight) {
    	int randomValue = threadSafeRandom.next(0,1000);
    	if(randomValue < upWeight){
    		return true;
		}
    	return false;
	}
	//判断职业是不是一样颜色的
	public static boolean isTheSameColor(List<Integer> occList) {
		int targetColor = 0;
		for(int color : occList){
			if(targetColor != 0 && targetColor != color){
				return false;
			}else{
				targetColor = color;
			}
		}
		return true;
	}


	//获取是加多少赚钱千分比
	//0是每有一个格子的加成赚速千分比 1是是不是有满格加成且加成值
	public static List<Integer> getEarnSpeedAddValueList(int blockCount,boolean isFull){
		List<Integer> resList = new ArrayList<>();
		for(int i = 0 ;i < earnSpeedList.size(); i++){
			int index1 = earnSpeedList.get(i).get(0);
			if(i + 1 < earnSpeedList.size()){
				int index2 = earnSpeedList.get(i + 1).get(0);
				if(blockCount >= index1 && blockCount < index2){
					resList.add(earnSpeedList.get(i).get(1));
					resList.add(isFull?earnSpeedList.get(i).get(2):0);
					break;
				}
			}else{
				//最后一个是所有的孔数的配置
				if(blockCount >= index1){
					resList.add(earnSpeedList.get(i).get(1));
					resList.add(isFull?earnSpeedList.get(i).get(2):0);
					break;
				}
			}
		}
		if(resList.size() == 0){
			resList.add(0);
			resList.add(0);
		}
		return resList;
	}

	public static int getVehiclesTurnCostItem(int quality) {
		if (quality == 3) {
			return vehiclesTurnCostItemCq;
		}
		if (quality == 4) {
			return vehiclesTurnCostItemWs;
		}
		return 0;
	}

	@Override
	public boolean init() throws Exception {
		return reload();
	}

	@Override
	public boolean stop() {
		return false;
	}

	@Override
	public boolean save() {
		return false;
	}

	@Override
	public boolean reloadConfig() {
		Map<Integer, VehicleSoulBlockInfo> tempBlockInfoMap = new ConcurrentHashMap<>();
		List<String> tempList = new ArrayList<>();
		tempList = StringUtils.stringToStringList(GameConfig.VEHICLES_SOUL_BLOCK_INFO,"\\|");
		for(int i = 0 ; i < tempList.size() ; i++){
			String infoStr = tempList.get(i);
			List<String> infoStrList = StringUtils.stringToStringList(infoStr,";");
			VehicleSoulBlockInfo info = new VehicleSoulBlockInfo();
			info.setNum(i+1);
			info.setUpCost(infoStrList.get(0));
			info.setSetSoulNum(Integer.valueOf(infoStrList.get(1)));
			tempBlockInfoMap.put(info.getNum(),info);
		}
		vehicleSoulBlockInfoMap = tempBlockInfoMap;

		Map<Integer, VehicleSoulShapeInfo> tempShapeInfoMap = new ConcurrentHashMap<>();
		Map<Integer, List<VehicleSoulShapeInfo>> tempVehicleSoulShapeNumMap = new ConcurrentHashMap<>();;
		tempList = StringUtils.stringToStringList(GameConfig.VEHICLES_SOUL_BLOCK_SHAPE,"#");
		for(int i = 0 ; i < tempList.size() ; i++){
			String infoStr = tempList.get(i);
			List<String> infoStrList = StringUtils.stringToStringList(infoStr,"=");
			VehicleSoulShapeInfo info = new VehicleSoulShapeInfo();
			info.setId(Integer.valueOf(infoStrList.get(0)));
			info.setInfo(infoStrList.get(1));
			info.setWeight(Integer.valueOf(infoStrList.get(2)));
			tempShapeInfoMap.put(info.getId(),info);
			if(!tempVehicleSoulShapeNumMap.containsKey(info.getNum())){
				tempVehicleSoulShapeNumMap.put(info.getNum(),new ArrayList<>());
			}
			tempVehicleSoulShapeNumMap.get(info.getNum()).add(info);
		}
		vehicleSoulShapeInfoMap = tempShapeInfoMap;
		vehicleSoulShapeNumMap = tempVehicleSoulShapeNumMap;


		Map<Integer, VehicleSoulQualityInfo> tempQualityInfoMap = new ConcurrentHashMap<>();
		tempList = StringUtils.stringToStringList(GameConfig.VEHICLES_SOUL_QUALITY_INFO,"#");
		for(int i = 0 ; i < tempList.size() ; i++){
			String infoStr = tempList.get(i);
			List<String> infoStrList = StringUtils.stringToStringList(infoStr,"\\|");

			VehicleSoulQualityInfo info = new VehicleSoulQualityInfo();
			info.setQuality(i + 1);
			info.setNum(Integer.valueOf(infoStrList.get(0)));
			info.setReward1(infoStrList.get(1));
			info.setReward2(infoStrList.get(2));
			info.setUpWeight(Integer.valueOf(infoStrList.get(3)));
			tempQualityInfoMap.put(info.getQuality(),info);
		}

		vehicleSoulQualityInfoMap = tempQualityInfoMap;


		Map<Integer,Integer> tempEntryQualityWeightMap = new ConcurrentHashMap<>();

		tempList = StringUtils.stringToStringList(GameConfig.VEHICLES_SOUL_WORD_INFO,"\\|");
		for(int i = 0 ; i < tempList.size() ; i++){
			String infoStr = tempList.get(i);
			List<Integer> infoIntegerList = StringUtils.stringToIntegerList(infoStr,";");
			tempEntryQualityWeightMap.put(infoIntegerList.get(0),infoIntegerList.get(1));
		}

		entryQualityWeightMap = tempEntryQualityWeightMap;


		washEntryCostList = StringUtils.stringToStringList(GameConfig.VEHICLES_SOUL_WORD_WASH_COST,"\\|");


		List<List<Integer>> tempEarnSpeedList = new ArrayList<>();
		List<String> tempStrList = StringUtils.stringToStringList(GameConfig.VEHICLES_SOUL_BLOCK_UNLOCK_EFFECT,"\\|");
		for(String infoStr : tempStrList){
			tempEarnSpeedList.add(StringUtils.stringToIntegerList(infoStr,";"));
		}
		earnSpeedList = tempEarnSpeedList;

		VEHICLES_PEERLESS_GUARANTEES = GameConfig.VEHICLES_PEERLESS_GUARANTEES;
		vehiclesTurnCostItemCq = GameConfig.VEHICLES_ITEM_CHANGE_QUALITY_3;
		vehiclesTurnCostItemWs = GameConfig.VEHICLES_ITEM_CHANGE_QUALITY_4;
		return true;
	}


	@Override
	public boolean reloadData() throws Exception {
		return true;
	}


	public static RandomHelper getThreadSafeRandom() {
		return threadSafeRandom;
	}
}
